﻿
using Core.SimpleTemp.Common;
using Core.SimpleTemp.Common.Authorization;
using Core.SimpleTemp.Common.PagingQuery;
using Core.Toolkit.Core.Repositories;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Text;
using System.Threading.Tasks;


namespace Core.Toolkit.ServiceCollectionExtensions
{
    public static class ToolkitServiceCollectionExtensions
    {
        private const string WEBAPP_OPTIONS = "WebAppOptions";


        /// <summary>
        /// 添加认证
        /// </summary>
        /// <param name="services"></param>
        /// <param name="webAppOptions"></param>
        public static void AddToolkitAuthentication(this IServiceCollection services, WebAppOptions webAppOptions)
        {
            services.AddAuthentication(option =>
            {
                option.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;

            }).AddCookie(option =>
            {
                //为了给Api相应401去掉此设置相应302 并且重定向到指定URL
                option.Events.OnRedirectToLogin = (context) =>
                {
                    context.Response.StatusCode = 401;
                    return Task.CompletedTask;
                };
                option.Events.OnRedirectToAccessDenied = (context) =>
                {
                    context.Response.StatusCode = 403;
                    return Task.CompletedTask;
                };
                option.Cookie.Name = "Authentication_Cookie";
                option.Cookie.SameSite = SameSiteMode.None;
                //设置Cookie过期时间 ,如不设置 默认为14天挺恐怖的 注意如不设置票据过期时间，默认票据采用此时间
                option.ExpireTimeSpan = TimeSpan.FromMinutes(webAppOptions.TimeOutOfLogin);
                //当Cookie过期时间已达一半时，是否重置ExpireTimeSpan 每次认证确认，handle 在Http响应重写Cookie
                option.SlidingExpiration = true;
                //option.TicketDataFormat = new TicketDataFormat(new AesDataProtector());
            }).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, JwtOption =>
            {
                //禁用Https模式
                JwtOption.RequireHttpsMetadata = false;
                JwtOption.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateAudience = true,
                    ValidAudience = webAppOptions.JwtValidAudience,
                    ValidateIssuer = true,
                    ValidIssuer = webAppOptions.JwtValidIssuer,
                    //是否验证失效时间
                    ValidateLifetime = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(webAppOptions.JwtIssuerSigningKey))
                };

            });
        }

        /// <summary>
        /// 配置信息注冊
        /// </summary>
        /// <param name="services"></param>
        /// <param name="webAppOptions"></param>
        /// <param name="configuration"></param>
        public static void AddToolkitWebAppOptions(this IServiceCollection services, WebAppOptions webAppOptions, IConfiguration configuration)
        {
            services.Configure<WebAppOptions>(configuration.GetSection(WEBAPP_OPTIONS));
        }

        /// <summary>
        /// //配置跨域规则 [EnableCors("any")]
        /// </summary>
        /// <param name="services"></param>
        public static void AddToolkitCors(this IServiceCollection services)
        {
            services.AddCors(options =>
            {
                options.AddPolicy("any", builder =>
                {
                    builder.AllowAnyOrigin() //允许任何来源的主机访问
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials();//指定处理cookie
                });
            });
        }

        /// <summary>
        /// Toolkit服务加载
        /// </summary>
        /// <param name="services"></param>
        /// <param name="webAppOptions"></param>
        /// <param name="configuration"></param>
        /// <param name="logger"></param>
        public static void AddToolkit(this IServiceCollection services, WebAppOptions webAppOptions, IConfiguration configuration, ILogger logger)
        {
            services.AddTransient(typeof(SQLHelper));
            services.AddToolkitAuthentication(webAppOptions);
            services.AddToolkitWebAppOptions(webAppOptions, configuration);
            services.AddToolkitCors();
            services.AutoDi(logger);
            //自定义授权
            //services.AddTransient<IGetFunctionCode, SysLoginService>();
            services.AddTransient<IAuthorizationHandler, PermissionAuthorizationHandler>();
            //services.AddAuthorization();
            //采用内存版分布缓存 方便以后切换Redis
            services.AddDistributedMemoryCache(); //services.AddDistributeRedisCache(null);
            services.AddTransient(typeof(IPagingQueryModelBuild<>), typeof(PagingQueryModelBuildFromBody<>));
            services.AddHttpClient();
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

        }
    }
}
